<?php
namespace Core;

abstract class Controller {

	/**
	 * 操作不存在时被调用，默认响应 404 错误，也可在控制器类中重载__call()方法，这样即可根据请求的操作名称和参数进行更丰富的处理
	 *
	 * @param string $method
	 * @param array $args
	 * @return void
	 */
	public function __call($method, $args) {
		if ('Controller\\' . HHO::$config['controller.void'] == get_class($this)) {
			Error::h404("Controller '" . HHO::$controller . "' not found");
		} else {
			$debug = debug_backtrace();
			
			if ($debug[2]['class'] == 'Core\HHO') {
				Error::h404("Action '" . HHO::$controller . '->' . HHO::$action . "' not found");
			} else {
				trigger_error("Call to undefined method {$debug[1]['class']}::{$debug[1]['function']}()", E_USER_ERROR);
			}
		}
	}

	/**
	 * 获得当前操作的视图对象
	 *
	 * @return View
	 */
	final public function getView() {
		static $instance = null;
		
		$instance || ($instance = new View());
		
		return $instance;
	}

	/**
	 * 向视图对象中注册一个模板变量
	 *
	 * @param string $name 变量名
	 * @param mixed $value 变量值
	 */
	final public function assign($name, $value = null) {
		return $this->getView()->assign($name, $value);
	}

	/**
	 * 调用视图中的 display() 方法，开始处理视图层，最终输出响应至客户端的内容
	 *
	 * @param string $template 使用的模板
	 */
	final public function display($template = null) {
		if (!$template) {
			foreach (debug_backtrace() as $trace) {
				if (isset($trace['class']) && strstr($trace['class'], '\\', true) == 'Controller') {
					$template = substr(strstr($trace['class'], '\\'), 1) . '/' . ucfirst($trace['function']);
					
					break;
				}
			}
		}
		
		$this->getView()->display($template);
	}

	/**
	 * 控制器类的单实例模式实现，若需要实现多实例，则允许使用 new 创建或重写此方法以实现多实例模式
	 *
	 * @return Object
	 */
	static public function getInstance() {
		static $instance = array();
		
		$class = get_called_class();
		
		if (!isset($instance[$class])) {
			$instance[$class] = new static();
		}
		
		return $instance[$class];
	}
}